/*
*************************************************
				Copyagent
	------------------------------------------
	            baza_date.c
*************************************************
Adauga suport pentru interactiunea cu baza de date
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <mysql/mysql.h>
#include "crawler_lib.h"
#include "baza_date_lib.h"
#include "mining_lib.h"


MYSQL mysql;
MYSQL_RES *res;
MYSQL_ROW row; 




/*
void  pune_prop_cu_cuvantul_in_vector(char * cuvant,int * vector_aparitii);
-------------------------------------------------
Pune id-urile propozitiilor in care se regaseste cuvantul in vectorul de aparitii
-------------------------------------------------
char * cuvant: cuvantul ale carui aparitii in propozitii caut
int * vector_aparitii: vectorul in care se vor pune id-urile propozitiilor
return int : numarul prop_
*/
void pune_prop_cu_cuvantul_in_vector(char * cuvant, Vector vector_aparitii)
{
	char query[DB_QUERY_MAX_LEN]; 
	int ret, i=0;
	
	memset(query,0,DB_QUERY_MAX_LEN);
	sprintf(query,"SELECT prop_id FROM copyagent.cuvinte where (cuvant = '%s')", cuvant);
	ret = mysql_query(&mysql,query);
	if (ret != 0 )
	{
		printf("%s \n",mysql_error(&mysql));
		fflush(stdout);
	}
	
	i = 0;
	res = mysql_use_result(&mysql);
	while(row = mysql_fetch_row(res))
	{
		vector_aparitii.vector[i++] = atoi(row[0]);
	}	
	vector_aparitii.size = i;
	mysql_free_result(res);
	
	return;
}


/*
int nr_prop_cu_cuvantul(char * cuvant);
-------------------------------------------------
Afla numarul de propozitii ce contin cuvantul dat.
-------------------------------------------------
char * cuvant: cuvantul ale carui aparitii in propozitii caut
ret int: nr_de propozitii
*/
int nr_prop_cu_cuvantul(char * cuvant)
{
	char query[DB_QUERY_MAX_LEN]; 
	int ret, nr_prop = 0;
	sprintf(query,"SELECT count(prop_id) FROM copyagent.cuvinte where (cuvant = '%s')", cuvant);
	ret = mysql_query(&mysql,query);
	if (ret != 0 )
	{
		printf("%s \n",mysql_error(&mysql));
		fflush(stdout);
	}
		
	res = mysql_use_result(&mysql);
	while(row = mysql_fetch_row(res))
		nr_prop = atoi(row[0]);
	
	mysql_free_result(res);
	
	return nr_prop;

}

/*
void pune_cuvinte_prop_in_vector(int prop_id, char ** vector_cuvinte, Vector vector_cuvinte_id);
-------------------------------------------------
Pune cuvintele propozitiei prpp_id in vectorul vector_cuvinte
-------------------------------------------------
int prop_id: id-ul propozitiei ale carui cuvinte le vreau
char **  vector_cuvinte: vectorul in care se vor pune cuvintele
Vector  vector_cuvinte_id: vectorul in care se vor pune id-urile cuvintelor
*/
void pune_cuvinte_prop_in_vector(int prop_id, char ** vector_cuvinte, Vector vector_cuvinte_id)
{
	char query[DB_QUERY_MAX_LEN]; 
	int ret, i=0;
	
	memset(query,0,DB_QUERY_MAX_LEN);
	sprintf(query,"SELECT cuvant, cuvant_id FROM copyagent.cuvinte where (prop_id = '%d')", prop_id);
	ret = mysql_query(&mysql,query);
	if (ret != 0 )
	{
		printf("%s \n",mysql_error(&mysql));
		fflush(stdout);
	}
	
	i = 0;
	res = mysql_use_result(&mysql);
	while(row = mysql_fetch_row(res))
		if (strlen(row[0]) < LUNG_MAX_CUV) 
		{
			sprintf(vector_cuvinte[i], row[0]);
			vector_cuvinte_id.vector[i] = atol (row[1]);
			i++;
		}	
	
	vector_cuvinte_id.size = i - 1;
	mysql_free_result(res);
	
	return;
}

/*
int nr_cuvinte_in_prop(int prop_id);
-------------------------------------------------
Afla numarul de cuvinte pentru propozitia data 
-------------------------------------------------
int prop_id: id-ul propozitiei al carui numar de cuvinte il vreau
ret int: nr_de_cuvinte al propozitiei
*/
int nr_cuvinte_in_prop(int prop_id)
{
	char query[DB_QUERY_MAX_LEN]; 
	int ret, nr_cuvinte = 0;
	sprintf(query,"SELECT count(prop_id) FROM copyagent.cuvinte where (prop_id = '%d')", prop_id);
	ret = mysql_query(&mysql,query);
	if (ret != 0 )
	{
		printf("%s \n",mysql_error(&mysql));
		fflush(stdout);
	}
		
	res = mysql_use_result(&mysql);
	while(row = mysql_fetch_row(res))
		nr_cuvinte = atoi(row[0]);
	
	mysql_free_result(res);
	
	return nr_cuvinte;

}

/*
int ia_urmatoarea_propozitie(int my_rank);
-------------------------------------------------
Gaseste primul id de propozitie care nu a fost inca marcat
ca fiind tratata , id care are restul impartirii la my_rank == 0.
Apoi marcheaza propozitia ca fiind vizitata
-------------------------------------------------
return int: intoarce id-ul acestei propozitii sau -1 daca nu mai sunt propozitii
*/
int ia_urmatoarea_propozitie(int my_rank)
{
	char query[DB_QUERY_MAX_LEN]; 
	int ret, id_prop;
	sprintf(query,"SELECT min(id_aparitie)	FROM copyagent.aparitii	where (vizitata = '0')AND (id_aparitie %% 4 = %d )", my_rank);
	//sprintf(query,"SELECT min(id_aparitie)	FROM copyagent.aparitii	where (vizitata = '0')");
	printf("%s\n", query	);
	ret = mysql_query(&mysql,query);
	if (ret != 0 )
	{
		printf("%s \n",mysql_error(&mysql));
		fflush(stdout);
	}
		
	res = mysql_use_result(&mysql);
	row = mysql_fetch_row(res);
	if (row != NULL)
 		id_prop = atoi(row[0]);
	else
		return -1;

	mysql_free_result(res);
	
	sprintf(query,"UPDATE copyagent.aparitii SET vizitata = '1'where (id_aparitie = '%d')", id_prop);
	ret = mysql_query(&mysql,query);
	if (ret != 0 )
	{
		printf("%s \n",mysql_error(&mysql));
		fflush(stdout);
	}
	
	return id_prop;
}




/*
int insert_cuvint_into_db(char * cuvant, int id_prop);
-------------------------------------------------
Insereaza un cuvant din propozitia id_prop in baza de date
-------------------------------------------------
char * cuvant: cuvantul
int id_prop: id-ul propozitiei din care face parte cuvantul
return int: id-ul propozitiei
*/
int insert_cuvint_into_db(char * cuvant, int id_prop)
{
	int ret_value;
	if (strlen(cuvant) > FILENAME_LENGTH)
		return -1;
	if (id_prop < 0)
		return -1;
	char query[DB_QUERY_MAX_LEN]; 
	sprintf(query,"INSERT into copyagent.cuvinte (cuvant , prop_id) VALUES ('%s','%d')", cuvant, id_prop); 
	ret_value = mysql_query(&mysql,query);
	if (ret_value != 0 )
	{
		printf("%s \n",mysql_error(&mysql));
		fflush(stdout);
	}
	return ret_value;
   
}

/*
void sparge_prop_in_cuvinte(char * unit,int id_prop);
-------------------------------------------------
Introduce cuvintele din propozitia unit in tabela de cuvinte.
Fiecare cuvant va pastra si id-ul propozitiei din care provine
------------------------------
char * unit: propozitia din care trebui extrase cuvintele
int id_prop: id-ul propozitiei
*/
void sparge_prop_in_cuvinte(char * unit,int id_prop)
{
	char * propozitie = (char *)(malloc(FILENAME_LENGTH));
	char * tokeni = (char *)(malloc(15));
	char * cuvant;

	if (unit == NULL)
		return;
	sprintf(tokeni,"'\".,;=-:)(}*{/ ");
	if( strlen(unit) > FILENAME_LENGTH )
		return;
	strcpy(propozitie, unit);

	cuvant = strtok (propozitie,tokeni);
	while (cuvant != NULL)
	{
		if  (strlen (cuvant) > LUNG_MIN_CUV)
		{
			insert_cuvint_into_db(cuvant, id_prop);
			
		}
		cuvant = strtok (NULL,tokeni);
	}
	return ;

	
}
/*
int insert_prop_into_db(char * prop, char * url);
-------------------------------------------------
Insereaza o propozitie de la o adresa URL in baza de date
-------------------------------------------------
char * prop: propozitia care a fost gasita
char * url: adresa la care a fost gasita
MYSQL mysql: baza de date in care se stocheaza informatia
return int: id-ul propozitiei
*/
int insert_prop_into_db(char * prop, char * url)
{
	int ret_value;
	replaceChars(prop,'\'','_');
	if (strlen(url) > FILENAME_LENGTH)
		return -1;
	if (strlen(prop) > FILENAME_LENGTH)
		return -1;
	char query[DB_QUERY_MAX_LEN]; 
	sprintf(query,"INSERT into copyagent.aparitii (propozitie, domeniu, url_complet, data_propozitie) VALUES ('%s','%s','%s', NOW())", prop, extrageHostDinURL(url), url); 
   	ret_value = mysql_query(&mysql,query);
	if (ret_value != 0 )
	{
		printf("%s \n",mysql_error(&mysql));
		fflush(stdout);
	}
	ret_value = mysql_insert_id(&mysql);
   	return ret_value;
   
}

/*
int mysql_connection_start()
-------------------------------------------------
Initiaza conexiunea la serverul Mysql
-------------------------------------------------
return int: 0 daca s-a initiat cu succes, !=0 altfel
*/
int mysql_connection_start()
{
	

	mysql_init(&mysql);
	if (!mysql_real_connect(&mysql,"10.0.0.1","copyagent","pentium2",NULL/*variation #2*/,0,NULL,0))
	//if (!mysql_real_connect(&mysql,"lup","copyagent","pentium2",NULL/*variation #2*/,0,NULL,0)) 	 
	{
		printf( "Failed to connect to MySQL: Error: %s\n", mysql_error(&mysql));
		fflush(stdout);
		return 1;
	}
	return 0;
}

/*
int mysql_connection_end()
-------------------------------------------------
Inchide conexiunea la serverul Mysql
-------------------------------------------------
*/
void mysql_connection_end()
{
	mysql_close(&mysql);
}


/*
int sparge_prop_bufferul_pentru_bd(char * buffer, char  * current_url);
-------------------------------------------------
Sparge bufferul in unitati de propozitii.
Separarea se face in functie de US - unit separator.
Unitatile rezultate se pun pe cate o linie noua in fisierul destinatie.
Rezultatul este 0 daca spargerea s-a facut cu succes. Diferit de 0 atlfel.
-------------------------------------------------
char * buffer:	buffer-ul de spart
char * current_url: url-ul din care a fost extrasa propozitia
return int:	0 daca totul a fost in regula. !=0 altfel
*/
int sparge_prop_bufferul_pentru_bd(char * buffer, char  * current_url)
{

	char * unit;
	char * tokeni = (char *)(malloc(2));
	sprintf(tokeni,"%c.",US);
	int id_prop = 0;
	
	unit = strtok (buffer,tokeni);
	while (unit != NULL)
	{
		if  (strlen (unit) > LUNG_MIN_PROP)
		{
			id_prop = insert_prop_into_db(unit, current_url);
			if (id_prop > 0)
				sparge_prop_in_cuvinte(unit, id_prop);
		}
		unit = strtok (NULL,tokeni);
	}
	return 0;
}

/*
int salveaza_rezultatele_in_bd(Vector rezultate, Vector tuplu_cuvinte, int id_propozitie);
-------------------------------------------------
Introduce in baza de date rezultatele mineritului
-------------------------------------------------
Vector rezultate: vectorul ce contine id-urile propozitiilor in care se regasesc cuvintele din tuplu_cuvinte
Vector tuplu_cuvinte: vectorul ce contine id-urile cuvintelor din tuplu
*/
int salveaza_rezultatele_in_bd(Vector rezultate, Vector tuplu_cuvinte)
{
	/*
		Mai intai inserez in tupluri obtinand un id_tuplu unic
		Apoi inserez in cuvinte
		Apoi inserez in propozitii
	*/
	char query[DB_QUERY_MAX_LEN]; 
	int ret_value = 0, i = 0, tuplu_id = 0;
	printf("AM intrat\n");
	/*Ma asigur de id-ul unic al tuplului*/
	memset(query,0,DB_QUERY_MAX_LEN);
	sprintf(query,"INSERT into copyagent.tupluri () VALUES ()"); 
   	ret_value = mysql_query(&mysql,query);
	if (ret_value != 0 )
	{
		printf("%s \n",mysql_error(&mysql));
		fflush(stdout);
	}
	tuplu_id = mysql_insert_id(&mysql);
	printf("tuplu_id: %d\n",tuplu_id);
	for( i = 0 ; i < tuplu_cuvinte.size ; i++)
	{
		//sleep(1);
		memset(query,0,DB_QUERY_MAX_LEN);
		sprintf(query,"INSERT into copyagent.tupluri_cuvinte (id_tuplu, id_cuvant) VALUES ('%d','%ld')", tuplu_id, tuplu_cuvinte.vector[i]); 
		ret_value = mysql_query(&mysql,query);
		if (ret_value != 0 )
		{
			printf("%s \n",mysql_error(&mysql));
			fflush(stdout);
		}
	}

	for( i = 0 ; i < rezultate.size ; i++)
		{
			memset(query,0,DB_QUERY_MAX_LEN);
			sprintf(query,"INSERT into copyagent.tupluri_propozitii (id_tuplu, id_propozitie) VALUES ('%d','%ld')", tuplu_id, rezultate.vector[i]); 
			ret_value = mysql_query(&mysql,query);
			if (ret_value != 0 )
			{
				printf("%s \n",mysql_error(&mysql));
				fflush(stdout);
			}
		}


	return ret_value;


}
